package com.py.credit.service.impl;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSONObject;
import com.py.credit.common.rest.RestServiceResult;
import com.py.credit.dao.OutInterfaceDao;
import com.py.credit.entity.WarnRuleEntity;
import com.py.credit.entity.WarnSchemeEntity;
import com.py.credit.service.ColumnService;
import com.py.credit.service.OutInterfaceService;
import com.py.credit.service.RemoteBaseService;
import com.py.framework.core.common.Page;

@Service
public class OutInterfaceServiceImpl implements OutInterfaceService {

	@Autowired
	private OutInterfaceDao outInterfaceDao;
	@Autowired
	private RemoteBaseService remoteUseService;
	@Autowired
	private ColumnService columnService;


	@Override
	public Integer checkIsExist(String tybm) {
		return outInterfaceDao.checkIsExist(tybm);
	}

	@Override
	public void addRule(WarnRuleEntity map) {
		outInterfaceDao.addRule(map);
	}

	@Override
	public void addRuleAssociation(String ruleId, String schemeId) {

		outInterfaceDao.addRuleAssociation(ruleId, schemeId);

	}

	@Override
	public Map<String, Object> getRuleByTybm(String tybm, String kId, String appKey, String homesecretKey)
			throws Exception {
		Map<String, Object> map = new HashMap<>();
		Integer totalCount = 0;
		map.put("cf", 0);
		map.put("relateData", "");
		map.put("relateCount", 0);
		Integer cf = 0;
		Integer relateCount = 0;
		cf += methodForGetRule(kId, tybm);
		totalCount = cf + relateCount;
		map.put("cf", cf);
		map.put("relateCount", relateCount);
		map.put("totalCount", totalCount);
		return map;
	}

	@Override
	public Map<String, Object> getRuleByPersonTask(Map<String, Object> map, String kId,String tybm, String appKey, String homesecretKey)
			throws Exception {
		Map<String, Object> warnCount = null;
				if (map != null) {
				 warnCount = getWarnCount(map, kId,tybm);
				} else {
				 warnCount = getWarnCount(kId, tybm);
				}		        	
		return warnCount;
	}

	@Override
	public Map<String, Object> getRuleByComTask(Map<String, Object> map, String kId, String tybm) {
		if (map != null) {
			Map<String, Object> warnCount = getWarnCount(map, kId, String.valueOf(map.get("tybm")));
			return warnCount;
		} else {
			Map<String, Object> warnCount = getWarnCount(kId, tybm);
			return warnCount;
		}
	}

	@Override
	public List<Map> getCompanyInfo(String name, String kId, Page page) {
		if (("100000").equals(kId)) {
			return outInterfaceDao.getCompanyInfoForPage(name, page);
		} else {
			return outInterfaceDao.getPersonInfoForPage(name, page);
		}
	}

	@Override
	public void deleteRuleByTybm(String tybm) {
		outInterfaceDao.deleteRuleByTybm(tybm);
	}

	@Override
	public void updateRuleById(WarnRuleEntity entity) {
		outInterfaceDao.updateRuleById(entity);
	}

	@Override
	public void addScheme(WarnSchemeEntity entity,List<String> tybms, MultipartFile file) throws Exception {
		outInterfaceDao.addScheme(entity);
		try {
		if(file != null && !file.isEmpty()) {
			Workbook wb = this.getwb(file);
			
			tybms = this.getFileTybm(entity.getMainType(),wb);
			for(int i=0;i<tybms.size();i++) {
				//去重校验
				int istrue = outInterfaceDao.selectrepeat(tybms.get(i),entity.getMainType());
				if(istrue>0) {
					tybms.remove(i);
				}
			}
			
		}
	
			if("100000".equals(entity.getMainType())) {
				outInterfaceDao.addFrList(tybms,entity.getRecordId());
			}else if("1000001".equals(entity.getMainType())) {
				outInterfaceDao.addZrrList(tybms,entity.getRecordId());
			}else if("1000002".equals(entity.getMainType())) {
				outInterfaceDao.addFqyList(tybms,entity.getRecordId());
			}
		}catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	private Workbook getwb(MultipartFile file) throws Exception {
		Workbook wb = null;
		// 获取文件的后缀
        String fileType = null;
        if (file != null) {
            // 获取文件后缀
            if (file.getOriginalFilename().contains(".")) {
                fileType = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."),
                        file.getOriginalFilename().length());
            }
        } else {
            throw new Exception("上传的文件不得为空");
        }
        if (!".xls".equalsIgnoreCase(fileType) && !".xlsx".equalsIgnoreCase(fileType)) {
        	throw new Exception("上传的文件格式不支持");
        }
        try {
            if (".xls".equalsIgnoreCase(fileType)) {
                wb = new HSSFWorkbook(file.getInputStream());
            } else if (".xlsx".equalsIgnoreCase(fileType)) {
                wb = new XSSFWorkbook(file.getInputStream());
            } else {
            	throw new Exception("上传的文件格式不支持");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
		return wb;
	}

	private List<String> getFileTybm(String mainType, Workbook wb) throws Exception {
		List<String> tybms = new ArrayList<>();
		  Sheet sheet = wb.getSheetAt(0);
	        int rowNum = sheet.getLastRowNum();
	        Row row;
	        for (int j = 1; j <= rowNum; j++) {
	            row = sheet.getRow(j);
	            if (row == null) {
	                continue;
	            }
	            String name = getCellFormatValue(row.getCell(0));
	            String tyshxydm = getCellFormatValue(row.getCell(1));
	            if (name.equals("")) {
	                continue;
	            }
	            try {
		           String tybm = outInterfaceDao.getFileTybm(name,tyshxydm,mainType);
		           tybms.add(tybm);
	            }catch (Exception e) {
					System.out.println(e.getMessage());
				}
	        }
	        if(tybms.size() <= 0) {
	        	throw new Exception("文件无匹配数据，请重试");
	        }

		return tybms;
	}
	 private String getCellFormatValue(Cell cell) {
	        String cellvalue = "";
	        if (cell != null) {
	            // 判断当前Cell的Type
	            switch (cell.getCellType()) {
	                case Cell.CELL_TYPE_NUMERIC: // 如果当前Cell的Type为NUMERIC
	                case Cell.CELL_TYPE_FORMULA: {
	                    // 判断当前的cell是否为Date
	                    if (DateUtil.isCellDateFormatted(cell)) {
	                        // 如果是Date类型则，转化为Data格式
	                        // data格式是带时分秒的：2013-7-10 0:00:00
	                        // cellvalue = cell.getDateCellValue().toLocaleString();
	                        // data格式是不带带时分秒的：2013-7-10
	                        Date date = cell.getDateCellValue();
	                        cellvalue = date.toLocaleString();
	                    } else {// 如果是纯数字
	                        // 取得当前Cell的数值
	                        cellvalue = String.valueOf((int) cell.getNumericCellValue());
	                    }
	                    break;
	                }
	                case Cell.CELL_TYPE_STRING:// 如果当前Cell的Type为STRING
	                    // 取得当前的Cell字符串
	                    cellvalue = cell.getRichStringCellValue().getString();
	                    break;
	                default:// 默认的Cell值
	                    cellvalue = "";
	            }
	        } else {
	            cellvalue = "";
	        }
	        return cellvalue;
	    }
	@Override
	public void updateScheme(WarnSchemeEntity entity, List<String> tybms, MultipartFile file) throws Exception {
		outInterfaceDao.updateScheme(entity);
		outInterfaceDao.delQyxx(entity.getRecordId(),entity.getMainType());
		if(file != null && !file.isEmpty()) {
			Workbook wb = this.getwb(file);
			
			tybms = this.getFileTybm(entity.getMainType(),wb);
		}
		if("100000".equals(entity.getMainType())) {
			outInterfaceDao.addFrList(tybms,entity.getRecordId());
		}else if("1000001".equals(entity.getMainType())) {
			outInterfaceDao.addZrrList(tybms,entity.getRecordId());
		}else if("1000002".equals(entity.getMainType())) {
			outInterfaceDao.addFqyList(tybms,entity.getRecordId());
		}
		
	}

	@Override
	public void addRealateIndex() {
		List<Map<String, String>> list = remoteUseService.getIndexInfo("");
		outInterfaceDao.deleteRealateIndex();
		if (list.size() > 0) {
			outInterfaceDao.addRealateIndex(list);
		}
	}

	@Override
	public void updateSchemeStatus(String status, String recordId) {
		outInterfaceDao.updateSchemeStatus(status, recordId);
	}

	@Override
	public List<Map<String, Object>> selectComInfo() {
		return outInterfaceDao.selectComInfo();
	}

	@Override
	public List<Map<String,Object>> selectPersonInfo() {
		return outInterfaceDao.selectPersonInfo();
	}

	@Override
	public List<Map<String, Object>> selectUnComInfo() {
		return outInterfaceDao.selectUnComInfo();
	}
	
	@Override
	public List<WarnSchemeEntity> selectSchemeForPage(String name, Page page,String type,String deptName,Long deptId,Long userId) {
		return outInterfaceDao.selectSchemeForPage(name, page,type,deptName,deptId,userId);
	}

	@Override
	public void addStatistics(List<Map<String, String>> list) {
		outInterfaceDao.addStatistics(list);
	}

	
	@Override
	public List<Map<String, String>> getWarnInfoData(String type, String name, Page page,String tybm,String deptid) {
		List<Map<String, String>> data = new ArrayList<Map<String,String>>();
		if (("100000").equals(type)) {
			data = outInterfaceDao.getWarnInfoDataFrForPage(name, page,tybm,deptid);  
		} else {
			data = outInterfaceDao.getWarnInfoDataZrrForPage(name, page,tybm,deptid);
		}
		for (Map<String, String> map : data) {
			if(map.get("relate_index")!= null) {
				List<String> asList = Arrays.asList(map.get("relate_index").split(","));
				if(asList != null && asList.size()>0) {
					String indexName = outInterfaceDao.SelectIndexSource(asList);	
					map.put("IndexName", indexName);
				}
	
			}
		}
		return data;
	}

	@Override
	public List<WarnRuleEntity> selectRuleForPage(String name, String mainType, Page page,Long deptId,Long userId) {
		return outInterfaceDao.selectRuleForPage(name, mainType, page,deptId,userId);
	}

	@Override
	public Integer checkIsExistScheme(String mainType, String status) {
		return outInterfaceDao.checkIsExistScheme(mainType, status);
	}

	@Override
	public List<Map<String, String>> selectRuleForBind(String mainType) {
		return outInterfaceDao.selectRuleForBind(mainType);
	}

	@Override
	public void updateAssociationDel(String schemeId) {
		outInterfaceDao.updateAssociationDel(schemeId);

	}

	@Override
	public void deleteRuleById(String id) {
		outInterfaceDao.deleteRuleById(id);
	}

	@Override
	public List<Map<String, String>> getPeopleForPage(String tybm, Page page, String name) {
		return outInterfaceDao.getPeopleForPage(tybm, page, name);
	}

	@Override
	public List<Map<String, String>> getComForPage(String tybm, Page page, String name) {
		return outInterfaceDao.getComForPage(tybm, page, name);
	}
	
	@Override
	public void addModelTest() {
		outInterfaceDao.deleteModelTest();
		List<Map<String, Object>> data = remoteUseService.getRuleData("", "");
		if(data!= null && data.size()>0) {
	    outInterfaceDao.addModelTest(data);	
		}
	}

	@Override
	public List<Map<String, Object>> getModelTestData(String tybm) {
		List<String> list = Arrays.asList(tybm.replaceAll(" ", "").split(","));
		return outInterfaceDao.getModelTestData(list);
	}
	
	public Map<String,Object> getWarnCount(Map<String, Object> ruleData, String schemeId, String tybm) {
		Integer count = 0;
		List<String> returnList = new ArrayList<>();
		Map<String,Object> returnMap = new HashMap<>();
		StringBuffer sb = new StringBuffer();
		List<WarnRuleEntity> rule = outInterfaceDao.selectRuleByScheme(schemeId);
		if (rule.size() > 0 && ruleData != null && !("").equals(ruleData)) {
			for (WarnRuleEntity item : rule) {
				if (item.getLimitScore() != null) {
					if (Double.parseDouble(String.valueOf(ruleData.get("score"))) < item.getLimitScore()) {
						count++;
						returnList.add(item.getId());
						if(sb.indexOf(item.getRecord_id()) ==-1) {
							sb.append(item.getRecord_id())
							  .append(",");
						}
					}
				}
				if (item.getRank() != null) {
					List<String> list = Arrays.asList(item.getRank().split(","));
					for (String key : list) {
						if (String.valueOf(ruleData.get("rank")).equals(key)) {
							count++;
							returnList.add(item.getId());
							if(sb.indexOf(item.getRecord_id()) ==-1) {
								sb.append(item.getRecord_id())
								  .append(",");
							}
						}
					}
				}
				if (item.getRelateIndex() != null) {
					List<Map<String, String>> list = outInterfaceDao
							.getRelateIndex(Arrays.asList(item.getRelateIndex()));
					if (list.size() > 0) {
						for (Map<String, String> map2 : list) {
							String value = columnService.getValueBySql(map2.get("callContent"), tybm);
							if (value != null && !("").equals(value)) {
								count += Integer.parseInt(value);
								returnList.add(item.getId());
								if(Integer.parseInt(value)>0) {
									if(sb.indexOf(item.getRecord_id()) ==-1) {
										sb.append(item.getRecord_id())
										.append(",");
									}
								}
							}
						}
					}
				}
			}
		} else if(rule.size() > 0 && (ruleData == null || ("").equals(ruleData))){
			for (WarnRuleEntity item : rule) {
				if (item.getRelateIndex() != null) {
					List<Map<String, String>> list = outInterfaceDao
							.getRelateIndex(Arrays.asList(item.getRelateIndex()));
					if (list.size() > 0) {
						for (Map<String, String> map2 : list) {
							String value = columnService.getValueBySql(map2.get("callContent"), tybm);
							if (value != null && !("").equals(value)) {
								count += Integer.parseInt(value);
								returnList.add(item.getId());
								if(Integer.parseInt(value)>0) {
									if(sb.indexOf(item.getRecord_id()) ==-1) {
										sb.append(item.getRecord_id())
										.append(",");
									}
								}
							}
						}
					}
				}

			}
		}
		returnMap.put("scheme", sb.toString());
		returnMap.put("count", count);
		returnMap.put("list", returnList);
		return returnMap;
	}

	private Map<String,Object> getWarnCount(String kId, String tybm) {
		Integer count = 0;
		StringBuffer sb = new StringBuffer();
		List<WarnRuleEntity> rule = outInterfaceDao.selectRuleByScheme(kId);
		List<String> returnList = new ArrayList<>();
		Map<String,Object> returnMap = new HashMap<>();
		for (WarnRuleEntity item : rule) {
			if (item.getRelateIndex() != null) {
				List<Map<String, String>> list = outInterfaceDao
						.getRelateIndex(Arrays.asList(item.getRelateIndex().split(",")));
				if (list.size() > 0) {
					for (Map<String, String> map2 : list) {
						String value = columnService.getValueBySql(map2.get("callContent"), tybm);
						if (value != null && !("").equals(value)) {
							count += Integer.parseInt(value);
							returnList.add(item.getId());
							if(Integer.parseInt(value)>0) {
								if(sb.indexOf(item.getRecord_id()) ==-1) {
									sb.append(item.getRecord_id())
									.append(",");
								}
							}
						}
					}
				}
			}

		}
		returnMap.put("scheme", sb.toString());
		returnMap.put("count", count);
		returnMap.put("list", returnList);
		return returnMap;
	}

	private static LinkedList<Map<String, Object>> getDate(int j, List<Map<String, Object>> data) {
		LinkedList<Map<String, Object>> list = new LinkedList<>();
		int preCount = 0;
		int count = 0;
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		for (int i = j - 1; i > -1; --i) {
			Calendar calendar = Calendar.getInstance();
			calendar.add(Calendar.DATE, -i);
			for (Map<String, Object> item : data) {
				if (item.get("date").equals(df.format(calendar.getTime()))) {
					Map<String, Object> dataMap = new HashMap<>();
					dataMap.put(String.valueOf(item.get("date")), item.get("count"));
					list.add(dataMap);
					count++;
					break;
				}
			}
			if (preCount == count) {
				Map<String, Object> dataMap = new HashMap<>();
				dataMap.put(String.valueOf(df.format(calendar.getTime())), 0);
				list.add(dataMap);
			}
			preCount = count;
		}
		return list;
	}
	
	
	private static LinkedList<Map<String, Object>> getDateType(int j, List<Map<String, Object>> data) {
		LinkedList<Map<String, Object>> list = new LinkedList<>();
		Map<String,String> map = new HashMap<String,String>();
		map.put("1", "0");
		map.put("2", "0");
		map.put("3", "0");
		map.put("4", "0");
		int preCount = 0;
		int count = 0;
		long dateDiff = 0;
		if(j==0) {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			try {
				Date endDate = df.parse(String.valueOf(data.get(0).get("date")));
				Date startDate = df.parse(String.valueOf(data.get(data.size()-1).get("date")));
				long diff = endDate.getTime() - startDate.getTime();
				dateDiff = diff/1000/60/60/24;
			} catch (ParseException e1) {
				e1.printStackTrace();
			}
			for (int i = Integer.parseInt(String.valueOf(dateDiff)); i > -1; --i) {
				Calendar calendar = Calendar.getInstance();
				try {
					calendar.setTime(df.parse(String.valueOf(data.get(0).get("date"))));
				} catch (ParseException e) {
					e.printStackTrace();
				}
				calendar.add(Calendar.DATE, -i);
				for (Map<String, Object> item : data) {
					if (item.get("date").equals(df.format(calendar.getTime()))) {
						Map<String, Object> dataMap = new HashMap<>();
						dataMap.put(String.valueOf(item.get("date")), item.get("count"));
						list.add(dataMap);
						count++;
						break;
					}
				}
				if (preCount == count) {
					Map<String, Object> dataMap = new HashMap<>();
					dataMap.put(String.valueOf(df.format(calendar.getTime())), map);
					list.add(dataMap);
				}
				preCount = count;
			}
			return list;	
		}else {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			for (int i = j - 1; i > -1; --i) {
				Calendar calendar = Calendar.getInstance();
				calendar.add(Calendar.DATE, -i);
				for (Map<String, Object> item : data) {
					if (item.get("date").equals(df.format(calendar.getTime()))) {
						Map<String, Object> dataMap = new HashMap<>();
						dataMap.put(String.valueOf(item.get("date")), item.get("count"));
						list.add(dataMap);
						count++;
						break;
					}
				}
				if (preCount == count) {
					Map<String, Object> dataMap = new HashMap<>();
					dataMap.put(String.valueOf(df.format(calendar.getTime())), map);
					list.add(dataMap);
				}
				preCount = count;
			}
			return list;	
		}
		
	}
	
	
	private List<Map<String, Object>> getFormatData(List<Map<String, String>> data) {
		
		List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
		for (int i=0;i < data.size();i++) {
			Map<String,Object> returnOutMap = new HashMap<String, Object>();
			Map<String,Object> returnInMap = new HashMap<String, Object>();
			String flag = data.get(i).get("create_time");
			returnInMap.put(data.get(i).get("type"), data.get(i).get("count"));
			data.remove(i);
			for (int j=0;j < data.size();j++) {
			if(flag.equals(data.get(j).get("create_time"))) {
			returnInMap.put(data.get(j).get("type"), data.get(j).get("count"));
			data.remove(j);
			j--;
			}
			}
			if(!returnInMap.containsKey("1")) {
				returnInMap.put("1", "0");
			}
			if(!returnInMap.containsKey("2")) {
				returnInMap.put("2", "0");			
			}
			if(!returnInMap.containsKey("3")) {
				returnInMap.put("3", "0");
			}
			if(!returnInMap.containsKey("4")) {
				returnInMap.put("4", "0");
			}
			returnOutMap.put("date",flag);
			returnOutMap.put("count",returnInMap);
			list.add(returnOutMap);
			i--;
		}
		
		return list;
	}
	
	public static void main(String[] args) {
		List<Map<String,Object>> list = new ArrayList<Map<String,Object>>();
		Map<String,Object> map = new HashMap<String, Object>();
		list.add(map);
		map.put("date", "2019-08-18");
		map.put("count", 1);
	System.out.println(JSONObject.toJSON(getDate(7, list)));
	}
	
	
	private Integer methodForGetRule(String kId,String tybm) {
		Integer count = 0;
		List<WarnRuleEntity> rule = outInterfaceDao.selectRuleByScheme(kId);
		List<Map<String, Object>> ruleData = this.getModelTestData(tybm);
		for (WarnRuleEntity item : rule) {
			if(ruleData.size()>0) {
				if (item.getLimitScore() != null) {
					if (Double.parseDouble(String.valueOf(ruleData.get(0).get("score"))) < item.getLimitScore()) {
						count++;
					}
				}
				if (item.getRank() != null) {
					List<String> list = Arrays.asList(item.getRank().split(","));
					for (String key : list) {
						if (String.valueOf(ruleData.get(0).get("rank")).equals(key)) {
							count++;
						}
					}
				}	
			}
			if (item.getRelateIndex() != null) {
				List<Map<String, String>> list = outInterfaceDao
						.getRelateIndex(Arrays.asList(String.valueOf(item.getRelateIndex()).split(",")));
				if (list.size() > 0) {
					for (Map<String, String> map2 : list) {
						String value = columnService.getValueBySql(map2.get("callContent"), tybm);
						if (!StringUtils.isEmpty(value)) {
							if (("210001").equals(map2.get("relateSource"))
									|| ("210003").equals(map2.get("relateSource"))) {
								count+= Integer.valueOf(value);
							}
							if ((!("210001").equals(map2.get("relateSource"))
									&& (!("210003").equals(map2.get("relateSource"))))) {
								count += Integer.parseInt(value);
							}
						}
					}
				}
			}
		}
		return count;
	}
	
	@Override
	public List<Map<String, Object>> getCreditReportData(String tybm) {
		return outInterfaceDao.getCreditReportData(tybm);
	}

	@Override
	public void delete(Integer id) {
		//删除模型
		outInterfaceDao.delete(id);
		//删除模型对应的绑定规则
		outInterfaceDao.deleterule(id);
		
	}


	
	@Override
	public List<Map<String,String>> selectWarnDept() {
		
		return outInterfaceDao.selectWarnDept();
	}

	
	@Override
	public List<Map<String, String>> getWarnCompanyForPage(String type, String recordId, String mainType, Page page) {
	
		return outInterfaceDao.getWarnCompanyForPage(type, recordId, mainType,page);
	}
	

	@Override
	public List<Map<String, String>> getIsWarnCompanyForPage(String type, String recordId, String mainType, Page page) {
	
		return outInterfaceDao.getIsWarnCompanyForPage(type, recordId, mainType,page);
	}
	
}
